package com.sense.cloud.send.app;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.InetSocketAddress;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;

import org.jboss.resteasy.core.interception.PostMatchContainerRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import io.netty.channel.ChannelHandlerContext;

public class ChannelContainerContextFilter implements ContainerRequestFilter {
	public static final String HEADER_RESTEASY_CLIENT_IP = "X-Resteasy-Client-Ip";
	protected final Logger	logger	= LoggerFactory.getLogger(ChannelContainerContextFilter.class);

	// 获得请求的IP地址
	protected void getClientIP(PostMatchContainerRequestContext requestContext) {
			String ip = null;
			//互联网访问
			String s1 = requestContext.getHeaderString("X-Real-IP");
			if (s1 == null) {
				//互联网有代理访问
				s1 = requestContext.getHeaderString("X-Forwarded-For");
				if (s1 == null) {
					// 取socket 层 IP
					ip = getSocketRemoteAddrIp(requestContext);
				} else {
					ip = s1;
				}
			} else {
				ip = s1;
			}
			if(StringUtils.isEmpty(ip)){
				ip = "0.0.0.0";  //无法得到ip 时返回 0.0.0.0
			}
			requestContext.getHeaders().putSingle(HEADER_RESTEASY_CLIENT_IP, ip);
		}
		
	private String getSocketRemoteAddrIp(PostMatchContainerRequestContext requestContext) {
		try {
	        Field privateStringField = requestContext.getHttpRequest().getClass().  
	        		getDeclaredField("ctx");
	        privateStringField.setAccessible(true);
			ChannelHandlerContext ctx = (ChannelHandlerContext) privateStringField
					.get(requestContext.getHttpRequest());
			if(ctx!=null && ctx.channel()!=null){
				return  ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostAddress();
		}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}
    	return null;
	}

	public void filter(ContainerRequestContext requestContext) throws IOException {
		PostMatchContainerRequestContext ctx = (PostMatchContainerRequestContext) requestContext;
		getClientIP(ctx);
	}
}
